﻿using DapperBaseDal.Expressions;
using DapperExtensions;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace DapperBaseDal
{
    public abstract class BaseService<T> where T : class
    {
        public IBaseRepository<T> CurrentRepository
        {
            get { return this.SetRepository(); }
        }
        public abstract IBaseRepository<T> SetRepository();  //设置数据仓库
        public BaseService()
        {
        }

        #region 查询数量Count
        public int Count(object predicate = null)
        {
            return CurrentRepository.Count(predicate);
        }
        public int Count(Expression<Func<T, bool>> predicate)
        {
            return CurrentRepository.Count(predicate);
        }
        #endregion

        #region 查询单个实体
        public T Get(dynamic id)
        {
            return CurrentRepository.Get(id);
        }
        public T GetFirst(object predicate = null, object sort = null)
        {
            return CurrentRepository.GetFirst(predicate, sort);
        }
        public T GetFirst(Expression<Func<T, bool>> predicate)
        {
            return CurrentRepository.GetFirst(predicate);
        }
        public T GetFirst(Expression<Func<T, bool>> predicate, object sort)
        {
            return CurrentRepository.GetFirst(predicate, sort);
        }
        public T GetFirst(Expression<Func<T, bool>> predicate, IList<ISort> sort)
        {
            return CurrentRepository.GetFirst(predicate, sort);
        }
        public T GetFirst(Expression<Func<T, bool>> predicate, SortDirection ascending, params Expression<Func<T, object>>[] sortingExpression)
        {
            return CurrentRepository.GetFirst(predicate, ascending, sortingExpression);
        }
        #endregion

        #region 查询列表
        public IEnumerable<T> GetList(object predicate = null, object sort = null)
        {
            return CurrentRepository.GetList(predicate, sort);
        }
        public IEnumerable<T> GetList(object predicate, IList<ISort> sort)
        {
            return CurrentRepository.GetList(predicate, sort);
        }
        public IEnumerable<T> GetList(Expression<Func<T, bool>> predicate, IList<ISort> sort = null)
        {
            return CurrentRepository.GetList(predicate, sort);
        }
        public IEnumerable<T> GetList(Expression<Func<T, bool>> predicate, SortDirection ascending, params Expression<Func<T, object>>[] sortingExpression)
        {
            return CurrentRepository.GetList(predicate, ascending, sortingExpression);
        }

        #endregion

        #region 查询区间列表
        public IEnumerable<T> GetSet(int firstResult, int maxResults, object predicate, object sort)
        {
            return CurrentRepository.GetSet(firstResult, maxResults, predicate, sort);
        }
        public IEnumerable<T> GetSet(int firstResult, int maxResults, object predicate, IList<ISort> sort)
        {
            return CurrentRepository.GetSet(firstResult, maxResults, predicate, sort);
        }
        public IEnumerable<T> GetSet(int firstResult, int maxResults, Expression<Func<T, bool>> predicate, object sort)
        {
            return CurrentRepository.GetSet(firstResult, maxResults, predicate, sort);
        }
        public IEnumerable<T> GetSet(int firstResult, int maxResults, Expression<Func<T, bool>> predicate, IList<ISort> sort)
        {
            return CurrentRepository.GetSet(firstResult, maxResults, predicate, sort);
        }
        public IEnumerable<T> GetSet(int firstResult, int maxResults, Expression<Func<T, bool>> predicate, SortDirection ascending, params Expression<Func<T, object>>[] sortingExpression)
        {
            return CurrentRepository.GetSet(firstResult, maxResults, predicate, ascending, sortingExpression);
        }

        #endregion

        #region 查询分页列表
        public IEnumerable<T> GetPage(int pageIndex, int pageSize, out int totalCount, object predicate, object sort)
        {
            return CurrentRepository.GetPage(pageIndex, pageSize, out totalCount, predicate, sort);
        }
        public IEnumerable<T> GetPage(int pageIndex, int pageSize, out int totalCount, object predicate, IList<ISort> sort)
        {
            return CurrentRepository.GetPage(pageIndex, pageSize, out totalCount, predicate, sort);
        }
        public IEnumerable<T> GetPage(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> predicate, object sort)
        {
            return CurrentRepository.GetPage(pageIndex, pageSize, out totalCount, predicate, sort);
        }
        public IEnumerable<T> GetPage(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> predicate, IList<ISort> sort)
        {
            return CurrentRepository.GetPage(pageIndex, pageSize, out totalCount, predicate, sort);
        }
        public IEnumerable<T> GetPage(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> predicate, SortDirection ascending, params Expression<Func<T, object>>[] sortingExpression)
        {
            return CurrentRepository.GetPage(pageIndex, pageSize, out totalCount, predicate, ascending, sortingExpression);
        }
        #endregion

        #region 新增
        public dynamic Insert(T entity)
        {
            return CurrentRepository.Insert(entity);
        }
        public void Insert(IEnumerable<T> entities)
        {
            CurrentRepository.Insert(entities);
        }
        #endregion

        #region 修改
        public bool Update(T entity, bool ignoreAllKeyProperties = false)
        {
            return CurrentRepository.Update(entity, ignoreAllKeyProperties);
        }
        #endregion

        #region 删除
        public bool Delete(T entity)
        {
            return CurrentRepository.Delete(entity);
        }
        public bool Delete(object predicate)
        {
            return CurrentRepository.Delete(predicate);
        }
        public bool Delete(Expression<Func<T, bool>> predicate)
        {
            return CurrentRepository.Delete(predicate);
        }
        #endregion

        #region 异步方法
        public async Task<int> CountAsync(object predicate = null)
        {
            return await CurrentRepository.CountAsync(predicate);
        }
        public async Task<int> CountAsync(Expression<Func<T, bool>> predicate)
        {
            return await CurrentRepository.CountAsync(predicate);
        }
        public async Task<T> GetAsync(dynamic id)
        {
            return await CurrentRepository.GetAsync(id);
        }
        public async Task<T> GetFirstAsync(object predicate = null, object sort = null)
        {
            return await CurrentRepository.GetFirstAsync(predicate, sort);
        }
        public async Task<T> GetFirstAsync(Expression<Func<T, bool>> predicate)
        {
            return await CurrentRepository.GetFirstAsync(predicate);
        }
        public async Task<T> GetFirstAsync(Expression<Func<T, bool>> predicate, object sort)
        {
            return await CurrentRepository.GetFirstAsync(predicate, sort);
        }
        public async Task<T> GetFirstAsync(Expression<Func<T, bool>> predicate, IList<ISort> sort)
        {
            return await CurrentRepository.GetFirstAsync(predicate, sort);
        }
        public async Task<T> GetFirstAsync(Expression<Func<T, bool>> predicate, SortDirection ascending, params Expression<Func<T, object>>[] sortingExpression)
        {
            return await CurrentRepository.GetFirstAsync(predicate, ascending, sortingExpression);
        }
        public async Task<IEnumerable<T>> GetListAsync(object predicate = null, object sort = null)
        {
            return await CurrentRepository.GetListAsync(predicate, sort);
        }
        public async Task<IEnumerable<T>> GetListAsync(object predicate, IList<ISort> sort)
        {
            return await CurrentRepository.GetListAsync(predicate, sort);
        }
        public async Task<IEnumerable<T>> GetListAsync(Expression<Func<T, bool>> predicate, IList<ISort> sort = null)
        {
            return await CurrentRepository.GetListAsync(predicate, sort);
        }
        public async Task<IEnumerable<T>> GetListAsync(Expression<Func<T, bool>> predicate, SortDirection ascending, params Expression<Func<T, object>>[] sortingExpression)
        {
            return await CurrentRepository.GetListAsync(predicate, ascending, sortingExpression);
        }
        public async Task<IEnumerable<T>> GetSetAsync(int firstResult, int maxResults, object predicate, object sort)
        {
            return await CurrentRepository.GetSetAsync(firstResult, maxResults, predicate, sort);
        }
        public async Task<IEnumerable<T>> GetSetAsync(int firstResult, int maxResults, object predicate, IList<ISort> sort)
        {
            return await CurrentRepository.GetSetAsync(firstResult, maxResults, predicate, sort);
        }
        public async Task<IEnumerable<T>> GetSetAsync(int firstResult, int maxResults, Expression<Func<T, bool>> predicate, object sort)
        {
            return await CurrentRepository.GetSetAsync(firstResult, maxResults, predicate, sort);
        }
        public async Task<IEnumerable<T>> GetSetAsync(int firstResult, int maxResults, Expression<Func<T, bool>> predicate, IList<ISort> sort)
        {
            return await CurrentRepository.GetSetAsync(firstResult, maxResults, predicate, sort);
        }
        public async Task<IEnumerable<T>> GetSetAsync(int firstResult, int maxResults, Expression<Func<T, bool>> predicate, SortDirection ascending, params Expression<Func<T, object>>[] sortingExpression)
        {
            return await CurrentRepository.GetSetAsync(firstResult, maxResults, predicate, ascending, sortingExpression);
        }
        public async Task<Tuple<IEnumerable<T>, int>> GetPageAsync(int pageIndex, int pageSize, object predicate, object sort)
        {
            return await CurrentRepository.GetPageAsync(pageIndex, pageSize, predicate, sort);
        }
        public async Task<Tuple<IEnumerable<T>, int>> GetPageAsync(int pageIndex, int pageSize, object predicate, IList<ISort> sort)
        {
            return await CurrentRepository.GetPageAsync(pageIndex, pageSize, predicate, sort);
        }
        public async Task<Tuple<IEnumerable<T>, int>> GetPageAsync(int pageIndex, int pageSize, Expression<Func<T, bool>> predicate, object sort)
        {
            return await CurrentRepository.GetPageAsync(pageIndex, pageSize, predicate, sort);
        }
        public async Task<Tuple<IEnumerable<T>, int>> GetPageAsync(int pageIndex, int pageSize, Expression<Func<T, bool>> predicate, IList<ISort> sort)
        {
            return await CurrentRepository.GetPageAsync(pageIndex, pageSize, predicate, sort);
        }
        public async Task<Tuple<IEnumerable<T>, int>> GetPageAsync(int pageIndex, int pageSize, Expression<Func<T, bool>> predicate, SortDirection ascending, params Expression<Func<T, object>>[] sortingExpression)
        {
            return await CurrentRepository.GetPageAsync(pageIndex, pageSize, predicate, ascending, sortingExpression);
        }
        public async Task<dynamic> InsertAsync(T entity)
        {
            return await CurrentRepository.InsertAsync(entity);
        }
        public async Task InsertAsync(IEnumerable<T> entities)
        {
            await CurrentRepository.InsertAsync(entities);
        }
        public async Task<bool> UpdateAsync(T entity, bool ignoreAllKeyProperties = false)
        {
            return await CurrentRepository.UpdateAsync(entity, ignoreAllKeyProperties);
        }
        public async Task<bool> DeleteAsync(T entity)
        {
            return await CurrentRepository.DeleteAsync(entity);
        }
        public async Task<bool> DeleteAsync(object predicate)
        {
            return await CurrentRepository.DeleteAsync(predicate);
        }
        public async Task<bool> DeleteAsync(Expression<Func<T, bool>> predicate)
        {
            return await CurrentRepository.DeleteAsync(predicate);
        }
        #endregion

    }
}
